﻿#define  _CRT_SECURE_NO_WARNINGS 1
//C语⾔提供了⼀种⾮常特别的语法，就是 goto 语句和跳转标号， goto 语句可以实现在同⼀个函数
//内跳转到设置好的标号处。
//
//goto 语句如果使⽤的不当，就会导致在函数内部随意乱跳转，打乱程序的执⾏流程，所以我们的建
//议是能不⽤尽量不去使⽤；但是 goto 语句也不是⼀⽆是处，在多层循环的代码中，如果想快速跳出
//使⽤ goto 就⾮常的⽅便了。
//本来 for 循环想提前退出得使⽤ break ，⼀个 break 只能跳出⼀层 for 循环，如果3层循环嵌套
//就得使⽤3个 break 才能跳出循环，所以在这种情况下我们使⽤ goto 语句就会更加的快捷。
#include <stdio.h>
//int main()
//{
//	
//	printf("hehhe\n");
//	if (1)
//		goto end;  // 跳转到end去
//	printf("haha"); // 被跳过了，所以不打印
//
//end:
//	printf("end\n");
//	return 0;
//}

//int main()
//{
//again:
//	printf("hehe\n");  // 死循环的打印hehe
//	goto again;
//	return 0;
//}

// 关机程序  1.程序运行起来的时候，就开始倒计时60秒关机
// 但是如果你能输入：我是猪，就取消关机
// 关机命令 shutdown  -s 关机   -t 设置时间关机   shutdown -s -t 60  倒计时60s关机
// shutdown -a 取消关机
//在cmd命令提示符里面执行
// system -- 库函数 可以执行系统命令  需要头文件stdlib.h
// 两个字符串比相等的时候 不能使用== 应该使用strcmp 库函数 需要头文件string.h
#include <string.h>
#include <stdlib.h>

//int main()
//{
//	char input[20] = { 0 };
//	system("shutdown -s -t 60");
//again:
//	printf("请注意，你的电脑在1分钟内关机，如果输入：我是猪，就取消关机\n");
//
//	scanf("%s", input); // 输入的信息放到input数组中
//
//	// 判断input中存放的是不是我是猪
//	if (strcmp("我是猪",input) == 0)
//	{
//		system("shutdown -a");
//	}
//	else
//	{
//		goto again;
//	}
//	return 0;
//}
// 不用goto



//int main()
//{
//	char input[20] = { 0 };
//	system("shutdown -s -t 60");
//	while (1)
//	{
//		printf("请注意，你的电脑在1分钟内关机，如果输入：我是猪，就取消关机\n");
//
//		scanf("%s", input); // 输入的信息放到input数组中
//
//		// 判断input中存放的是不是我是猪
//		if (strcmp("我是猪", input) == 0)
//		{
//			system("shutdown -a");
//			break;
//		}
//	}
//
//	return 0;
//}


//写⼀个猜数字游戏
//游戏要求：
//1. 电脑⾃动⽣成1~100的随机数
//2. 玩家猜数字，猜数字的过程中，根据猜测数据的⼤⼩给出⼤了或⼩了的反馈，直到猜对，游戏结束

// 首先先生成随机数  c语言提供了一个rand函数，用于生成随机数  int rand(void)

//rand函数会返回⼀个伪随机数，这个随机数的范围是在0~RAND_MAX之间，这个RAND_MAX的⼤⼩是
//依赖编译器上实现的，但是⼤部分编译器上是32767。
//rand函数的使⽤需要包含⼀个头⽂件是：stdlib.h

#include <stdlib.h>
//int main()
//{
//	printf("%d\n", rand());
//	printf("%d\n", rand());
//	printf("%d\n", rand());
//	printf("%d\n", rand());
//	printf("%d\n", rand());  // 发现不管运行多少次生成的随机数结果都一样
//	return 0;
//}

//我们可以看到虽然⼀次运⾏中产⽣的5个数字是相对随机的，但是下⼀次运⾏程序⽣成的结果和上⼀次
//⼀模⼀样，这就说明有点问题。
//如果再深⼊了解⼀下，我们就不难发现，其实rand函数⽣成的随机数是伪随机的，伪随机数不是真正
//的随机数，是通过某种算法⽣成的随机数。真正的随机数的是⽆法预测下⼀个值是多少的。⽽rand函
//数是对⼀个叫“种⼦”的基准值进⾏运算⽣成的随机数。
//之所以前⾯每次运⾏程序产⽣的随机数序列是⼀样的，那是因为rand函数⽣成随机数的默认种⼦是1。
//如果要⽣成不同的随机数，就要让种⼦是变化的

// C语⾔中⼜提供了⼀个函数叫 srand，⽤来初始化随机数的⽣成器的，srand的原型如下：void srand(unsigned int seed);

//程序中在调⽤ rand 函数之前先调⽤ srand 函数，通过 srand 函数的参数seed来设置rand函数⽣成随
//机数的时候的种⼦，只要种⼦在变化，每次⽣成的随机数序列也就变化起来了。
//那也就是说给srand的种⼦是如果是随机的，rand就能⽣成随机数；在⽣成随机数的时候⼜需要⼀个随
//机数，这就⽭盾了。 

//在程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的，因为时间时刻在发⽣变化的。
//在C语⾔中有⼀个函数叫 time ，就可以获得这个时间，time函数原型如下：
//time_t time(time_t * timer);

//time 函数会返回当前的⽇历时间，其实返回的是1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的
//差值，单位是秒。返回的类型是time_t类型的，time_t 类型本质上其实就是32位或者64位的整型类
//型。
//time函数的参数 timer 如果是⾮NULL的指针的话，函数也会将这个返回的差值放在timer指向的内存
//中带回去。
//如果 timer 是NULL，就只返回这个时间的差值。time函数返回的这个时间差也被叫做：时间戳。
//time函数的时候需要包含头⽂件：time.h

//如果只是让time函数返回时间戳，我们就可以这样写：
//time(NULL);//调⽤time函数返回时间戳，这⾥没有接收返回值

#include <time.h>
//int main()
//{
//	// 设置随机数的生成起点（种子）
//	srand((unsigned int)time(NULL));  // 要强制性转换 因为srand需要的值是unsigned
//	printf("%d\n", rand());
//	printf("%d\n", rand());
//	printf("%d\n", rand());  // 这样就能生成随机值了
//	printf("%d\n", rand());
//	return 0;
//}

//srand函数是不需要频繁调⽤的，⼀次运⾏的程序中调⽤⼀次就够了。

// 生成0-99之间的随机数  rand()%100 // 余数范围是0-99    生成1-100之间的随机数 rand()%100+1
// 生成100-200 100+rand()%(200-100+1) // 余数范围0-100 加100后就是100-200
// 生成a - b  a + rand（）%(b-a+1)  // 余数范围0到b-a  加a后就是  a-b
//int main()
//{
//	srand((unsigned int)time(NULL));
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d\n", rand() % 100 + 1);  // 生成1到100的随机数
//	}
//	return 0;
//}

//int main()
//{
//	srand((unsigned int)time(NULL));
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d\n",100+ rand() % (200 - 100 + 1)); // 生成100到200的随机数
//	}
//	return 0;
//}

// 函数  void 表示不返回值
//void menu()
//{
//	// 打印游戏菜单
//	printf("***********************\n");
//	printf("****** 1. play  *******\n");
//	printf("****** 0. exit  *******\n");
//	printf("***********************\n");
//}
//
//void game()
//{
//	// 游戏的逻辑
//	// 1. 生成随机数  我们可以在循环外头去生成，因为srand函数是不需要频繁调⽤的，⼀次运⾏的程序中调⽤⼀次就够了。
//	int r = rand() % 100 + 1;
//	// 2. 猜数字
//	int guess = 0;
//	while (1)
//	{
//		printf("请猜数字: ");
//		scanf("%d", &guess);
//		if (guess > r)
//		{
//			printf("猜大了\n");
//		}
//		else if (guess < r)
//		{
//			printf("猜小了\n");
//		}
//		else
//		{
//			printf("恭喜你猜对了\n");
//			break;
//		}
//	}
//}
//
//int main()
//{
//	int input = 0;  // 用于判断是否继续游戏
//	// 设置随机数的生成起点 整个工程只用调用一次就可以了
//	srand((unsigned int)time(NULL));
//	do
//	{
//		menu();  // 调用函数 打印菜单
//
//		// 选择
//		printf("请选择: ");
//		scanf("%d", &input);
//		switch (input)
//		{
//		case 1:
//			game(); // 玩游戏的函数
//			break;
//		case 0:
//			printf("退出游戏\n");
//			break;
//		default:
//			printf("选择错误，重新选择\n");
//			break;
//		}
//	} while (input);
//	return 0;
//}

// 还可以加上猜数字的次数限制，如果5次猜不出来，就算失败
void menu()
{
	// 打印游戏菜单
	printf("***********************\n");
	printf("****** 1. play  *******\n");
	printf("****** 0. exit  *******\n");
	printf("***********************\n");
}

void game()
{
	// 游戏的逻辑
	// 1. 生成随机数  我们可以在循环外头去生成，因为srand函数是不需要频繁调⽤的，⼀次运⾏的程序中调⽤⼀次就够了。
    int r = rand() % 100 + 1;

	// 2. 猜数字
	int guess = 0;
	int count = 5;
	while (count)  // 如果0次机会就不能再猜了
	{
		printf("还有%d次机会\n", count);
		printf("请猜数字: ");
		scanf("%d", &guess);
		if (guess > r)
		{
			printf("猜大了\n");
		}
		else if (guess < r)
		{
			printf("猜小了\n");
		}
		else
		{
			printf("恭喜你猜对了\n");
			break;
		}
		count--;
	}
	if (count == 0)
	{
		printf("你失败了,正确值是:%d\n", r);
	}
}

int main()
{
	int input = 0;  // 用于判断是否继续游戏
	// 设置随机数的生成起点 整个工程只用调用一次就可以了
	srand((unsigned int)time(NULL));
	do
	{
		menu();  // 调用函数 打印菜单

		// 选择
		printf("请选择: ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game(); // 玩游戏的函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误，重新选择\n");
			break;
		}
	} while (input);
	return 0;
}